from skillchallenge.models import *
from django.db.models import Q

class EventEngine:
    def add_event(self, scheduled = False, schedule_start = None,
                 schedule_end = None, player_will = False, recurring = False,
                 preconditions = [], actions = [], info='', description = '',
                 online = False, chatting = False, cost = 0):
        
        e = Event( scheduled = scheduled, schedule_start = schedule_start,
                   schedule_end = schedule_end, player_will = player_will,
                   recurring = recurring, info = info, description = description,
                   online = online, chatting = chatting, cost = cost)
        e.save()
        for action in actions:
            e.actions.add(action)
            
        
        for precon in preconditions:
            e.preconditions.add(precon)
            
        return e
    
    def not_fired(self):
        query = Q(timestamp__isnull = True) & \
            (Q(scheduled = False) | \
                (Q(schedule_start__datetime__lte = \
                   Tick.objects.latest().datetime) & \
                 Q(schedule_end__datetime__gte = \
                   Tick.objects.latest().datetime)))
        return Event.objects.filter(query).order_by('-timestamp__datetime')
    
    def fired(self):
        return Event.objects.filter(timestamp__isnull = False).filter(failed = False).order_by('-timestamp__datetime')
    
    def fired_by_info(self, info):
        return self.fired().filter(info__istartswith = info)
    
    def available_by_info(self, info):
        return self.not_fired().filter(info__istartswith = info)
    
    def player_available(self):
        return self.not_fired().filter(player_will = True)
      
    def player_fire(self, event):
        if event in self.player_available():
            self.fire(event)
    
    def fire_fail(self, event):
#        if event.scheduled and event.schedule_end < Tick.objects.latest():
         event.failed = True
         self.fire(event, True)
            
    def fire(self, event, failed = False):
        current_tick = Tick.objects.latest()
        event.timestamp = Tick.objects.create(tick=current_tick.tick)
        event.save()
        if not failed and event.recurring:
            preconditions = event.preconditions.all()
            actions = event.actions.all()
            e = Event.objects.create(
                                 scheduled = event.scheduled,
                                 schedule_start = event.schedule_start,
                                 schedule_end = event.schedule_end,
                                 player_will = event.player_will,
                                 recurring = event.recurring,
                                 timestamp = None,
                                 info = event.info,
                                 failed = event.failed,
                                 description = event.description,
                                 online = event.online,
                                 current_offline = event.current_offline,
                                 cost = event.cost,
                                 chatting = event.chatting)
            
            for precon in preconditions:
                e.preconditions.add(precon)
            for action in actions:
                e.actions.add(action)
